'use strict';

/**
 * 对 redis 发送的陌生人消息进行加工处理
 */

const Cons = require('../common/constants');
const fs = require("fs");
const ipcModel = require('../models/ipc.model');
const logger = require('../utils/logger');
const pushClient = require('../utils/redis_publish');
const resConfig = require('../../config/global_config').res;
const subClient = require('../utils/redis_subscribe');
const UserModel = require('../models/user.model');
const UserRecordModel = require('../models/record_user.model');
const StrangerRecordModel = require('../models/record_stranger.model');
const UserReg = require('../controllers/user');
const Config = require('../controllers/config');

let push_config = {};

/**
 * 将抓拍到的陌生人标记为陌生人类型，加入用户库
 * @param {*} message
 */
async function add_user_record_lib(message) {
    const urlPath = message.face_info.r_cp;
    const picPath = urlPath.substr(resConfig.base_record_uri.length,
        urlPath.length - resConfig.base_record_uri.length);
    //将记录图片保存到头像目录，并将其作为陌生人的头像
    const data = fs.readFileSync(resConfig.stranger_face_dir + picPath);
    const avatarPath = resConfig.avatar_dir + picPath;
    fs.writeFileSync(avatarPath, data);

    const tmp = picPath.split('_');

    const model = {
        _id: tmp[2],
        u_id: message.face_info._id,
        b_qp: [picPath],
        d_id: message.d_id,
        r_cp: picPath,
        u_hp: picPath,
        track_id: message.face_info.track_id,
        u_id: message.face_info._id,
        u_nm: message.attributes.name,
        u_st: 0,
        u_sx: 0,
        u_tp: 4,
        r_at: (new Date()).toISOString()
    }
    await UserRecordModel.insertMany(model);
    await StrangerRecordModel.remove({
        _id: tmp[2]
    });
}

/**
 * 根据 url 地址获取本地抓拍图片地址，并进行 base64 编码
 * @param {*} path
 * @return base64 编码后的数据
 */
function getFaceBase64Data(urlPath) {
    let localPath = urlPath.substr(resConfig.base_record_uri.length,
        urlPath.length - resConfig.base_record_uri.length);
    localPath = resConfig.stranger_face_dir + localPath;

    let data = fs.readFileSync(localPath);
    let base64Str = data.toString("base64");

    return base64Str;
}

/**
 * 注册陌生人
 * @param {*} message
 * @return 更新后的 message
 */
async function add_stranger(message) {
    let reg_json = {};
    reg_json.user_sex = "0";
    reg_json.user_type = Cons.USER_TYPE_STRANGER;
    reg_json.user_name = ((Math.random() * 100000) | 0).toString();
    reg_json.user_avatar = getFaceBase64Data(message.face_info.r_cp);
    reg_json.avatar_format = message.face_info.r_cp.substring(
        message.face_info.r_cp.lastIndexOf('.') + 1)
    logger.logInfo("\n" + '===== add_stranger - user_name:' +
        reg_json.user_name + "\n");
    let res = await UserReg.reg_stranger(reg_json);
    if (res.result == false) {
        logger.logInfo("\n" + '===== add_stranger - feature register failed:' +
            JSON.stringify(message) + "\n");
        return {
            is_success: false,
            msg: message,
        };
    }
    message.face_info._id = res.id;
    message.face_info.reg_img = {
        picdata: message.face_info.r_cp,
        type: reg_json.avatar_format
    };
    message.attributes = {};
    message.attributes.type = Cons.USER_TYPE_STRANGER.toString();
    message.attributes.name = reg_json.user_name.toString();
    await add_user_record_lib(message);
    return {
        is_success: true,
        msg: message,
    };
}

/**
 * 添加自定义信息
 * @param {*} message 
 * @return 更新后的 message 
 */
async function add_custom_info(message) {
    if (!message.face_info._id || message.face_info._id.length == 0) {
        return message;
    }
    if (!message.attributes)
        return message;
    const res = await UserModel.findOne({ _id: message.face_info._id }, { g_mk2: 1 });
    if (!res || !res.g_mk2) {
        return message;
    }
    message.attributes.g_mk2 = res.g_mk2;
    return message;
}


push_config.ready_callback = async function () {
    try {
        const ipc = await ipcModel.find();
        logger.logInfo("\n" + '===== Redis ReadyCallback  - ' + "=====\n");
        for (let i = 0; i < ipc.length; i++) {
            const item = ipc[i];
            subClient.subscribe(item._id);
        }
        pushClient.init();
    } catch (err) {
        logger.logError("\n" + '===== Redis subscribe error - ' + err + ' =====' + "\n");
    }
};

/**
 * 推送回调
 * @param channel
 * @param message
 * @returns {Promise.<void>}
 */
push_config.msg_callback = async function (channel, message) {
    try {
        if (message.liveness == Cons.RECORD_LIVENESS_NOT_LIVE) {
            return;
        }
        let jMsg = message;
        const ipcId = jMsg.d_id;
        const userId = jMsg.face_info._id;
        logger.logInfo("\n" + '===== Redis received - ipc: ' + ipcId +
            ', user: ' + userId + ' =====' + message + "\n");
        jMsg = await add_custom_info(jMsg);
        if (ipcId && (!userId || userId == '')) {
            let stranger = await Config.getStrangerSwitch();
            if (stranger.switch) {
                const res = await add_stranger(jMsg);
                if (!res.is_success) {
                    return;
                }
                jMsg = res.msg;
            }
        }
        pushClient.publish(Cons.REDIS_PUSH_FACE_CONFIG_HEAD + channel, jMsg)
    } catch (err) {
        logger.logError("\n" + '===== Redis received error - ' + err + ' =====' + "\n");
    }
};

push_config.quit_callback = async function () {
    pushClient.quit();
}


// 订阅推送
exports.push_config = push_config;